package io.kiki.sba.registry.store.jdbc.repository.impl;


import io.kiki.sba.registry.common.model.constants.ValueConstants;
import io.kiki.sba.registry.common.model.metaserver.ClientManagerAddress.AddressVersion;
import io.kiki.sba.registry.store.jdbc.domain.ClientManagerAddressDomain;
import io.kiki.sba.registry.store.jdbc.informer.DbEntryContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


public class ClientManagerAddressContainer implements DbEntryContainer<ClientManagerAddressDomain> {

    private static final Logger logger = LoggerFactory.getLogger(ClientManagerAddressContainer.class);

    private final Map<String, AddressVersion> clientOffData = new ConcurrentHashMap<>();

    private volatile Set<String> reduces = new HashSet<>();

    @Override
    public void onEntry(ClientManagerAddressDomain clientManagerAddress) {
        switch (clientManagerAddress.getOperation()) {
        case ValueConstants.CLIENT_OFF:
            clientOffData.put(clientManagerAddress.getAddress(), new AddressVersion(clientManagerAddress.getGmtCreateUnixMillis(), clientManagerAddress.getAddress(), clientManagerAddress.isSub()));
            reduces.remove(clientManagerAddress.getAddress());
            break;
        case ValueConstants.CLIENT_OPEN:
            clientOffData.remove(clientManagerAddress.getAddress());
            reduces.remove(clientManagerAddress.getAddress());
            break;
        case ValueConstants.REDUCE:
            clientOffData.remove(clientManagerAddress.getAddress());
            reduces.add(clientManagerAddress.getAddress());
            break;
        default:
            logger.error("error operation type: {}", clientManagerAddress);
            break;
        }
    }

    public ClientManagerAddress queryClientManagerAddress() {
        return new ClientManagerAddress(new HashMap<>(clientOffData), Collections.unmodifiableSet(reduces));
    }

    public class ClientManagerAddress {
        private final Map<String, AddressVersion> clientOffData;

        private final Set<String> reduces;

        public ClientManagerAddress(Map<String, AddressVersion> clientOffData, Set<String> reduces) {
            this.clientOffData = clientOffData;
            this.reduces = reduces;
        }


        public Map<String, AddressVersion> getClientOffData() {
            return clientOffData;
        }


        public Set<String> getReduces() {
            return reduces;
        }
    }
}
